<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
	</head>
	<body>
		<script>
			class myPromise {
				constructor(executor) {
					this.state = 'pending';
					this.value = undefined;
					this.reason = undefined;
					this.onResolvedCallbacks = [];
					this.onRejectedCallbacks = [];
					let resolve = value => {
						if (this.state === 'pending') {
							this.state = 'fulfilled';
							this.value = value;
							this.onResolvedCallbacks.forEach(fn => fn());
						}
					};
					let reject = reason => {
						if (this.state === 'pending') {
							this.state = 'rejected';
							this.reason = reason;
							this.onRejectedCallbacks.forEach(fn => fn());
						}
					};
					try {
						executor(resolve, reject);
					} catch (err) {
						reject(err);
					}
				}
				then(onFulfilled, onRejected) {
					onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
					onRejected = typeof onRejected === 'function' ? onRejected : err => {
						throw err
					};
					let promise2 = new myPromise((resolve, reject) => {
						if (this.state === 'fulfilled') {
							setTimeout(() => {
								try {
									let x = onFulfilled(this.value);
									resolvePromise(promise2, x, resolve, reject);
								} catch (e) {
									reject(e);
								}
							}, 0);
						};
						if (this.state === 'rejected') {
							setTimeout(() => {
								try {
									let x = onRejected(this.reason);
									resolvePromise(promise2, x, resolve, reject);
								} catch (e) {
									reject(e);
								}
							}, 0);
						};
						if (this.state === 'pending') {
							this.onResolvedCallbacks.push(() => {
								setTimeout(() => {
									try {
										let x = onFulfilled(this.value);
										resolvePromise(promise2, x, resolve, reject);
									} catch (e) {
										reject(e);
									}
								}, 0);
							});
							this.onRejectedCallbacks.push(() => {
								setTimeout(() => {
									try {
										let x = onRejected(this.reason);
										resolvePromise(promise2, x, resolve, reject);
									} catch (e) {
										reject(e);
									}
								}, 0)
							});
						};
					});
					return promise2;
				}
				catch (fn) {
					return this.then(null, fn);
				}
			}

			function resolvePromise(promise2, x, resolve, reject) {
				if (x === promise2) {
					return reject(new TypeError('Chaining cycle detected for promise'));
				}
				let called;
				if (x != null && (typeof x === 'object' || typeof x === 'function')) {
					try {
						let then = x.then;
						if (typeof then === 'function') {
							then.call(x, y => {
								if (called) return;
								called = true;
								resolvePromise(promise2, y, resolve, reject);
							}, err => {
								if (called) return;
								called = true;
								reject(err);
							})
						} else {
							resolve(x);
						}
					} catch (e) {
						if (called) return;
						called = true;
						reject(e);
					}
				} else {
					resolve(x);
				}
			}

			{
				function p1() {
					var promise1 = new Promise(function(resolve, reject) {
						console.log("p1的第一条输出语句");
						console.log("p1的第二条输出语句");
						resolve("p1完成");
					})
					return promise1;
				}
				function p2() {
					var promise2 = new Promise(function(resolve, reject) {
						console.log("p2的第一条输出语句");
						setTimeout(() => {
							console.log("p2的第二条输出语句");
							resolve("p2完成")
						}, 2000);
					})
					return promise2;
				}
				function p3() {
					var promise3 = new Promise(function(resolve, reject) {
						console.log("p3的第一条输出语句");
						console.log("p3的第二条输出语句");
						resolve("p3完成")
					});
					return promise3;
				}
				// Promise.all([p1(), p2(), p3()]).then(function(data) {
				// 	console.log(data, 'Promise.all');
				// })
				Promise.race([p1(), p2(), p3()]).then(function(data) {
					console.log(data, 'Promise.all');
				})
			}
		</script>
	</body>
</html>